using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Controls;
using System.Windows;
using System.Windows.Media;
using System.Diagnostics;
using System.Windows.Input;
using System.Collections.ObjectModel;
using System.ComponentModel;

namespace ShaderPad
{
    public class LogicalTreeItem:INotifyPropertyChanged
    {
        public LogicalTreeItem(DependencyObject element)
        {
            _element = element;
        }
        private bool _isSelected = false;
        private bool _isExpanded = false;

        public bool IsSelected
        {
            get
            {
                return _isSelected;
            }
            set
            {
                if (_isSelected != value)
                {
                    _isSelected = value;
                    RaisePropertyChangedEvent("IsSelected");
                }
            }
        }


        /// <summary>
        /// Gets/sets whether the TreeViewItem 
        /// associated with this object is expanded.
        /// </summary>
        public bool IsExpanded
        {
            get { return _isExpanded; }
            set
            {
                if (value != _isExpanded)
                {
                    _isExpanded = value;
                    this.RaisePropertyChangedEvent("IsExpanded");
                }

                // Expand all the way up to the root.
                if (_isExpanded)//&& _parent != null)
                {
                 //   _parent.IsExpanded = true;
                    LoadChildren();
                }

            }
        }

        void LoadChildren()
        {
            if (_children == null)
            {
                _children = new List<LogicalTreeItem>();
                foreach (DependencyObject obj in LogicalTreeHelper.GetChildren(_element))
                {
                    _children.Add(new LogicalTreeItem(obj));
                }
            }
        }

        public IEnumerable<LogicalTreeItem> Children
        {
            get
            {
                LoadChildren();
                return _children;
            }
        }

        public string Name
        {
            get
            {
                FrameworkElement fe = _element as FrameworkElement;
                if (fe != null && !String.IsNullOrEmpty(fe.Name))
                {
                    return Type + ":" + fe.Name;
                }
                else
                {
                    return Type;
                }
            }
        }

        public string Type
        {
            get
            {
                return _element.GetType().Name;
            }
        }

        private DependencyObject _element;
        public DependencyObject Element
        {
            get { return _element; }
        }

        private List<LogicalTreeItem> _children;

        protected void RaisePropertyChangedEvent(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        #endregion
    }

    public class VisualTreeItem
    {
        public VisualTreeItem(DependencyObject element)
        {
            _element = element;
        }

        public IEnumerable<VisualTreeItem> Children
        {
            get
            {
                if (_children == null)
                {
                    _children = new List<VisualTreeItem>(VisualTreeHelper.GetChildrenCount(_element));
                    for (int i = 0; i < VisualTreeHelper.GetChildrenCount(_element); i++)
                    {
                        _children.Add(new VisualTreeItem(VisualTreeHelper.GetChild(_element, i)));
                    }
                }
                return _children;
            }
        }

        public string Name
        {
            get
            {
                FrameworkElement fe = _element as FrameworkElement;
                if (fe != null && !String.IsNullOrEmpty(fe.Name))
                {
                    return Type + ":" + fe.Name;
                }
                else
                {
                    return Type;
                }
            }
        }

        public string Type
        {
            get
            {
                return _element.GetType().Name;
            }
        }

        private DependencyObject _element;
        public DependencyObject Element
        {
            get { return _element; }
        }

        private List<VisualTreeItem> _children;
    }

}
